<template>
  <div ref="chartRef" :style="{ height, width }"></div>
</template>
<script lang="ts">
  import { defineComponent, PropType, Ref, ref, watchEffect } from 'vue';
  import { useECharts } from '/@/hooks/web/useECharts';
  import * as MathUtil from '/@/utils/MathUtil';

  const COLOR_RED = '#F53F3F';
  const COLOR_GREEN = '#00B42A';

  export default defineComponent({
    name: 'BarSingleImg',
    props: {
      width: {
        type: String as PropType<string>,
        default: '100%',
      },
      height: {
        type: String as PropType<string>,
        default: '200px',
      },
      barWidth: {
        type: Number,
        default: 40,
      },
      dataList: {
        type: Array as PropType<{ name: string; value: number; color: string }[]>,
        default: () => [],
      },
      unit: String,
      formatter: String,
      showComment: {
        type: Boolean,
        default: true,
      },
      showUnit: {
        type: Boolean,
        default: true,
      },
    },
    setup(props) {
      const chartRef = ref<HTMLDivElement | null>(null);
      const { setOptions } = useECharts(chartRef as Ref<HTMLDivElement>);
      const echartsWidth = ref('');
      const echartsHeight = ref('');
      const getOption = () => {
        const formatter = props.formatter || 'currencyWNDFormatter|0';
        const [f, dot] = formatter.split('|');
        return {
          grid: {
            top: props.showComment ? '28%' : '15%',
            left: '15%',
            right: '15%',
            bottom: '15%',
          },
          tooltip: {
            show: false,
            triggerOn: 'none',
          },
          xAxis: {
            axisLabel: {
              show: false,
            },
            data: props.dataList.map((i) => i.name),
            axisTick: {
              show: false,
            },
          },
          yAxis: {
            show: false,
          },
          series: [
            {
              type: 'bar',
              barWidth: props.barWidth,
              itemStyle: {
                color: function (params) {
                  // 根据数据索引返回不同颜色
                  const colors = props.dataList.map((d) => d.color);
                  return colors[params.dataIndex];
                },
                barBorderRadius: [5, 5, 5, 5],
              },
              data: props.dataList.map((d) => d.value),
            },
            {
              type: 'custom',
              renderItem: renderItem,
              data: props.dataList.map((d) => d.value),
              z: 100,
            },
          ],
          graphic: !props.showComment
            ? ''
            : [
                {
                  top: 0,
                  right: 'center',
                  type: 'text',
                  style: {
                    text: props.showUnit ? (props.unit ? `单位：${props.unit}` : '') : '',
                    textAlign: 'left',
                  },
                },
                {
                  top: props.showUnit ? 20 : 0,
                  type: 'group',
                  right: 'center',
                  children: [
                    {
                      type: 'text',
                      right: 20,
                      style: {
                        text: `较${props.dataList[1].name}： ${MathUtil[f](props.dataList[0].value - props.dataList[1].value, dot)}`,
                        textAlign: 'right',
                      },
                    },
                    {
                      type: 'polygon',
                      right: 5,
                      top: 2,
                      shape: {
                        points: getTrianglePoint([0, 0], 4, props.dataList[0].value >= props.dataList[1].value),
                      },
                      style: {
                        fill: props.dataList[0].value >= props.dataList[1].value ? COLOR_GREEN : COLOR_RED,
                      },
                    },
                    {
                      type: 'text',
                      style: {
                        text: MathUtil.diffPercent2Formatter(props.dataList[0].value, props.dataList[1].value, 1),
                        fill: props.dataList[0].value >= props.dataList[1].value ? COLOR_GREEN : COLOR_RED,
                      },
                    },
                  ],
                },
                {
                  type: 'group',
                  right: 'center',
                  top: props.showUnit ? 40 : 20,
                  children: [
                    {
                      type: 'text',
                      right: 20,
                      style: {
                        text: `较${props.dataList[2].name}： ${MathUtil[f](props.dataList[0].value - props.dataList[2].value, dot)}`,
                        textAlign: 'right',
                      },
                    },
                    {
                      type: 'polygon',
                      right: 5,
                      top: 2,
                      shape: {
                        points: getTrianglePoint([0, 0], 4, props.dataList[0].value >= props.dataList[2].value),
                      },
                      style: {
                        fill: props.dataList[0].value >= props.dataList[2].value ? COLOR_GREEN : COLOR_RED,
                      },
                    },
                    {
                      type: 'text',
                      style: {
                        text: MathUtil.diffPercent2Formatter(props.dataList[0].value, props.dataList[2].value, 1),
                        fill: props.dataList[0].value >= props.dataList[2].value ? COLOR_GREEN : COLOR_RED,
                      },
                    },
                  ],
                },
              ],
        };
      };

      const renderItem = (params, api) => {
        const xValue = api.value(0);
        const yValue = api.value(1);
        const point = api.coord([xValue, yValue]);
        const point2 = api.coord([xValue, 0]);
        const yInterval = yValue >= 0 ? 15 : -15;
        if (!echartsWidth.value) {
          echartsWidth.value = api.getWidth();
          echartsHeight.value = api.getHeight();
        }
        const formatter = props.formatter || 'currencyWNDFormatter|0';
        const [f, dot] = formatter.split('|');

        return {
          type: 'group',
          children: [
            {
              type: 'text',
              style: {
                text: MathUtil[f](yValue, dot),
                x: point[0],
                y: point[1] - yInterval,
                fontSize: 12,
                textAlign: 'center',
                textBaseline: 'middle',
                fill: '#212A7C',
                // fill:
                //   yValue >= 0
                //     ? props.dataList[params.dataIndex].color
                //     : Color.COLOR_RED
              },
            },
            {
              type: 'text',
              style: {
                text: props.dataList[params.dataIndex].name,
                x: point2[0],
                y: point2[1] + yInterval,
                fontSize: 12,
                textAlign: 'center',
                textBaseline: 'middle',
              },
            },
          ],
        };
      };

      const getTrianglePoint = (point, interval = 5, rise = true) => {
        return [
          [point[0], rise ? point[1] - interval : point[1] + interval],
          [point[0] - interval, rise ? point[1] + interval : point[1] - interval],
          [point[0] + interval, rise ? point[1] + interval : point[1] - interval],
        ];
      };

      watchEffect(() => {
        if (props.dataList.length > 0) {
          setOptions(getOption());
        }
      });

      return { chartRef, echartsWidth, echartsHeight };
    },
  });
</script>
<style lang="less" scoped>
  .echarts {
    width: 100% !important;
    height: 100% !important;
  }
</style>
